/*
Copyright (C) 2021-2025 Casa Xu (also Zhiyan Xu) from HIT

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

/*
 * LOS_TASK.c
 * 该文件用于任务创建、队列创建、互斥量创建等OS初始化工作
 *  Created on: 2022年4月13日
 *      Author: CasaXu @LilacSat
 */
#include "LOS_SYS.h"
#include "HL_reg_system.h"
#include "svc.h"
#include "LOS_State.h"
#include "os_semphr.h"

#define Slave_Address  0x8
#define APP_START_ADDRESS 0x00200020

LOS_SNP_t SNP_test;
uint8_t FP_test[8];
extern uint8_t sd_flag;
extern uint8_t fatfs_arg;
extern FIL rfile;
extern FIL rfile_task;
extern FIL file_DTM;
FIL file_AskSize;
FIL rfile_crc32; //crc32计算专用
FIL file_cmos; //接收小相机照片专用
FIL file_tognd; //小相机照片从SD卡到测控专用
uint8_t max_flag = 0;
uint8_t FLASH_flag = 0;
uint32_t g_ulTransferAddress;

char threadtrace[] = "AOCS/r/n";

uint8_t FPstabuf = 0;
uint8_t SSYValid = 0;
uint8_t SSZValid = 0;

uint16_t mems_result[5] = {0xaaaa,0xaaaa,0xaaaa,0xaaaa,0xaaaa};

uint8_t TM_PACK_TEST[208];

//测试姿控算法运行时间
LOS_Tick_t aocsentertime = 0;
LOS_Tick_t aocsexittime = 0;
LOS_Tick_t aocstotaltime = 0;

//uint8_t DYN_PACK[508];

//遥控指令处理线程信号量
SemaphoreHandle_t BinSemphr_TC = NULL;

//在轨上注程序转存线程信号量
SemaphoreHandle_t BinSemphr_UP = NULL;

//磁强计采样信号量
SemaphoreHandle_t BinSemphr_MG = NULL;

//CRC32计算用缓冲区
uint8_t crcbuf[1028];

//载荷数据缓存区
uint8_t YH50_Data[22];
uint8_t EPS_Data[128];
uint8_t MagMe_Data[7];
uint8_t FotonAmur_Data[128];

/*任务创建基本步骤*/
//1.在LOS_Task_Init函数之前声明任务函数和函数句柄
//2.在LOS_Task_Init函数之中调用LOS_Task_Create函数创建任务
//3.在LOS_Task_Init函数之后定义任务函数内容


/*任务句柄与函数声明*/

/**
*  @任务名：Task_WD
*  @任务函数：Task_WD_Func
*  @任务句柄：Task_WD_Handle
*  @任务内容：看门狗线程
*/
LOS_TaskHandle_t Task_WD_Handle;
void Task_WD_Func(void *pvParameteres);


/**
*  @任务名：Task_AOCS
*  @任务函数：Task_AOCS_Func
*  @任务句柄：Task_AOCS_Handle
*  @任务内容：姿态控制进程
*/
LOS_TaskHandle_t Task_AOCS_Handle;
void Task_AOCS_Func(void *pvParameteres);

/**
*  @任务名：Task_Attitude
*  @任务函数：Task_Attitude_Func   
*  @任务句柄：Task_Attitude_Handle
*  @任务内容：卫星姿态信息获取进程
*/
LOS_TaskHandle_t Task_Attitude_Handle;
void Task_Attitude_Func(void *pvParameteres);

/**
*  @任务名：Task_Update
*  @任务函数：Task_Update_Func
*  @任务句柄：Task_Update_Handle
*  @任务内容：在轨上注进程
*/
#ifdef NOW_FLASH0
LOS_TaskHandle_t Task_Update_Handle;
void Task_Update_Func(void *pvParameteres);
#endif

/**
*  @任务名：Task_TM
*  @任务函数：Task_TM_Func
*  @任务句柄：Task_TM_Handle
*  @任务内容：遥测线程
*/
LOS_TaskHandle_t Task_TM_Handle;
void Task_TM_Func(void *pvParameteres);

/**
*  @任务名：Task_TC
*  @任务函数：Task_TC_Func
*  @任务句柄：Task_TC_Handle
*  @任务内容：遥控线程
*/
LOS_TaskHandle_t Task_TC_Handle;
void Task_TC_Func(void *pvParameteres);

/**
*  @任务名：Task_UP
*  @任务函数：Task_UP_Func
*  @任务句柄：Task_UP_Handle
*  @任务内容：上注转存线程，将上注到测控的板的程序转存至SD卡/FLASH
*/
LOS_TaskHandle_t Task_UP_Handle;
void Task_UP_Func(void *pvParameteres);

/**
*  @任务名：Task_UARTRcv
*  @任务函数：Task_UARTRcv_Func
*  @任务句柄：Task_UARTRcv_Handle
*  @任务内容：串口接收线程
*/
LOS_TaskHandle_t Task_UARTRcv_Handle;
void Task_UARTRcv_Func(void *pvParameteres);

/**
*  @任务名：Task_HighFreq
*  @任务函数：Task_HighFreq_Func
*  @任务句柄：Task_HighFreq_Handle
*  @任务内容：高频线程
*/
LOS_TaskHandle_t Task_HighFreq_Handle;
void Task_HighFreq_Func(void *pvParameteres);


/*操作系统初始化*/
void LOS_Task_Init(void)
{
    /*任务创建区*/
    /* 姿控线程 */
    LOS_Task_Create(Task_AOCS_Func,
                   "Task_AOCS",
                    LOS_Task_Stack8192B,
                    NULL,
                    LOS_Task_PriorityHigher,
                    &Task_AOCS_Handle);

    /* 采集线程 */
    LOS_Task_Create(Task_Attitude_Func,
                    "Task_Attitude",
                    LOS_Task_Stack2048B,
                    NULL,
                    LOS_Task_PriorityHigh,
                    &Task_Attitude_Handle);

    /* 在轨上注软件更新线程（默认挂起） */
    #ifdef NOW_FLASH0
    LOS_Task_Create(Task_Update_Func,
                    "Task_Update",
                    LOS_Task_Stack2048B,
                    NULL,
                    LOS_Task_PriorityMidHigh,
                    &Task_Update_Handle);
    #endif

    /* 串口接收线程 */                
    LOS_Task_Create(Task_UARTRcv_Func,
                    "Task_UARTRcv",
                    LOS_Task_Stack1024B,
                    NULL,
                    LOS_Task_PriorityMidHigh,
                    &Task_UARTRcv_Handle);

    /* 遥控线程 */
    LOS_Task_Create(Task_TC_Func,
                    "Task_TC",
                    LOS_Task_Stack2048B,
                    NULL,
                    LOS_Task_PriorityHigher,
                    &Task_TC_Handle);

    /* 遥测线程 */
    LOS_Task_Create(Task_TM_Func,
                    "Task_TM",
                    LOS_Task_Stack2048B,
                    NULL,
                    LOS_Task_PriorityMidMid,
                    &Task_TM_Handle);

    /* 上注转存线程 */
    LOS_Task_Create(Task_UP_Func,
                    "Task_UP",
                    LOS_Task_Stack4096B,
                    NULL,
                    LOS_Task_PriorityHighest,
                    &Task_UP_Handle);

    /* 看门狗喂狗线程 */
    LOS_Task_Create(Task_WD_Func,
                    "Task_WD",
                    LOS_Task_Stack512B,
                    NULL,
                    LOS_Task_PriorityLow,
                    &Task_WD_Handle);

    /* 低优先级高频线程 */
    LOS_Task_Create(Task_HighFreq_Func,
                    "Task_HighFreq",
                    LOS_Task_Stack1024B,
                    NULL,
                    LOS_Task_PriorityLower,
                    &Task_HighFreq_Handle);

    
    BinSemphr_TC = LOS_BinSemphr_Create();
    BinSemphr_UP = LOS_BinSemphr_Create();
    BinSemphr_MG = LOS_BinSemphr_Create();
}


/*任务函数内容定义*/

/** @fn Task_WD_Func(void *pvParameteres)
*   @brief 看门狗线程
*/
void Task_WD_Func(void *pvParameteres)
{
    static uint8_t flash_rewrite = 0;
    uint32_t program_normal = 0x66666666;
    TickType_t LastWakeTime;
    //uint8_t fatfs_flag = 0;  //用于判断FATFS是否初始化的标志位
    LastWakeTime = LOS_Task_GetTick();
    while(1)
    {
        LOS_WDT_Feed();
        if(flash_rewrite<11)   
        {    
            flash_rewrite++;
        }
/*
   EEPROM中标志取uint32_t型，从SD卡重新烧写程序后应将EEPROM擦除
   FlashBank7 Sector0 0XF0200000: FLASH0程序正常进入标志
   FlashBank7 Sector1 0XF0201000: FLASH1程序正常进入标志
   FlashBank7 Sector2 0XF0202000: FLASH0程序进入次数
   FlashBank7 Sector3 0XF0203000: FLASH1程序进入次数
   FlashBank7 Sector6 0XF0206000: 复位次数
*/
#ifdef NOW_FLASH0
        if (flash_rewrite==10)   //运行10次后，置标志位为正常
        {
            LOS_EnterAdminMode();
            LOS_Flash_EraseSector(Fapi_FlashBank7,0);
            LOS_Flash_WriteData(Fapi_FlashBank7, 0, 0, &program_normal, 4);
            LOS_ExitAdminMode();
        }
#endif

#ifdef NOW_FLASH1
        if (flash_rewrite==10)   //运行10次后，置标志位为正常
        {
            LOS_EnterAdminMode();
            LOS_Flash_EraseSector(Fapi_FlashBank7,1);
            LOS_Flash_WriteData(Fapi_FlashBank7, 1, 0, &program_normal, 4);
            LOS_ExitAdminMode();
        }
#endif
        LOS_Task_DelayUntil(&LastWakeTime, 100);
    }
}

/** @fn Task_TM_Func(void* pvParameteres)
*   @brief 遥测线程
*/
void Task_TM_Func(void* pvParameteres)
{
    TickType_t LastWakeTime;
    static uint8_t TM_PACK_D0[600];
    static uint8_t invsetcnt = 0;
    uint16_t frecnt = 0;
    uint8_t dbgcnt = 0;

    LOS_TM_FreCtrl = 20; //遥测频率控制
    LOS_TM_ID[0] = nID_OBC; //默认为基础遥测包
    LOS_TM_ID[1] = nID_OBC;
    LOS_TM_ID[2] = nID_OBC;
    LOS_TM_ID[3] = nID_OBC;
    LOS_TM_Type[0] = 0;     //默认类型
    LOS_TM_Type[1] = 0;
    LOS_TM_Type[2] = 0;
    LOS_TM_Type[3] = 0;

    LastWakeTime = LOS_Task_GetTick();
    while(1)
    {
        LOS_RTC_Calculate(LOS_Time_Sec);  
        if ((frecnt != LOS_TM_FreCtrl-1) && (frecnt != (uint16_t)((LOS_TM_FreCtrl / 4) - 1)) && (frecnt != (uint16_t)((LOS_TM_FreCtrl / 2) - 1)) && (frecnt != (uint16_t)((LOS_TM_FreCtrl / 4)*3 - 1)) && (frecnt != (uint16_t)((LOS_TM_FreCtrl / 4) * 5 - 1)) && (frecnt != (uint16_t)((LOS_TM_FreCtrl / 4) * 6 - 1)) && (frecnt < (LOS_TM_FreCtrl + (LOS_TM_InvTime * 10) - 1)))
        {
            frecnt++;
        }
        else if (frecnt == (uint16_t)((LOS_TM_FreCtrl / 4) - 1))  
        {
            taskENTER_CRITICAL();
            LOS_TMTC_TMPack(LOS_TM_ID[0], LOS_TM_Type[0], TM_PACK_D0);
            taskEXIT_CRITICAL();
            LOS_TMTC_TMSend(TM_PACK_D0, LOS_TMTC_GetTMPackSize(LOS_TM_ID[0], LOS_TM_Type[0]));
            if (LOS_DT_TMPERMIT == 0xAA)
            {
                LOS_DT_TMSend(TM_PACK_D0, LOS_TMTC_GetTMPackSize(LOS_TM_ID[0], LOS_TM_Type[0]));
            }
            frecnt++;
            if (LOS_TM_PackNum[0] > 0)
            {
                LOS_TM_PackNum[0] --;
            }
            else
            {
                LOS_TM_ID[0] = nID_OBC;
                LOS_TM_Type[0] = 0;
            }
        }
        else if (frecnt == (uint16_t)((LOS_TM_FreCtrl / 2) - 1))  
        {
            taskENTER_CRITICAL();
            LOS_TMTC_TMPack(LOS_TM_ID[1], LOS_TM_Type[1], TM_PACK_D0);
            taskEXIT_CRITICAL();
            LOS_TMTC_TMSend(TM_PACK_D0, LOS_TMTC_GetTMPackSize(LOS_TM_ID[1], LOS_TM_Type[1]));
            if (LOS_DT_TMPERMIT == 0xAA)
            {
                LOS_DT_TMSend(TM_PACK_D0, LOS_TMTC_GetTMPackSize(LOS_TM_ID[1], LOS_TM_Type[1]));
            }
            frecnt++;
            if (LOS_TM_PackNum[1] > 0)
            {
                LOS_TM_PackNum[1] --;
            }
            else
            {
                LOS_TM_ID[1] = nID_OBC;
                LOS_TM_Type[1] = 1;
            }
        }
        else if (frecnt == (uint16_t)((LOS_TM_FreCtrl / 4) * 3 - 1))  
        {
            taskENTER_CRITICAL();
            LOS_TMTC_TMPack(LOS_TM_ID[2], LOS_TM_Type[2], TM_PACK_D0);
            taskEXIT_CRITICAL();
            LOS_TMTC_TMSend(TM_PACK_D0, LOS_TMTC_GetTMPackSize(LOS_TM_ID[2], LOS_TM_Type[2]));
            if (LOS_DT_TMPERMIT == 0xAA)
            {
                LOS_DT_TMSend(TM_PACK_D0, LOS_TMTC_GetTMPackSize(LOS_TM_ID[2], LOS_TM_Type[2]));
            }
            frecnt++;
            if (LOS_TM_PackNum[2] > 0)
            {
                LOS_TM_PackNum[2] --;
            }
            else
            {
                LOS_TM_ID[2] = nID_OBC;
                LOS_TM_Type[2] = 2;
            }
        }
        else if (frecnt == LOS_TM_FreCtrl - 1)                   
        {
            taskENTER_CRITICAL();
            LOS_TMTC_TMPack(LOS_TM_ID[3], LOS_TM_Type[3], TM_PACK_D0);
            taskEXIT_CRITICAL();
            LOS_TMTC_TMSend(TM_PACK_D0, LOS_TMTC_GetTMPackSize(LOS_TM_ID[3], LOS_TM_Type[3]));
            if (LOS_DT_TMPERMIT == 0xAA)
            {
                LOS_DT_TMSend(TM_PACK_D0, LOS_TMTC_GetTMPackSize(LOS_TM_ID[3], LOS_TM_Type[3]));
            }
            if (LOS_TM_InvTime == 0)
            {
                frecnt = 0;   //如果间隔时间设置为了0，就只传输4个基础遥测包，所以直接归零
            }
            else
            {
                frecnt++;     //如果间隔时间设置不是0，允许在这一发送周期内插入其他的包（小相机照片包），所以继续累加
            }

            if (LOS_TM_PackNum[3] > 0)
            {
                LOS_TM_PackNum[3] --;
            }
            else
            {
                LOS_TM_ID[3] = nID_OBC;
                LOS_TM_Type[3] = 3;
            }
        }
        else if (frecnt == (uint16_t)((LOS_TM_FreCtrl / 4) * 5 - 1))  //24
        {
            if (LOS_CMOS_PICNUM < 100)
            {
                taskENTER_CRITICAL();
                switch(LOS_CMOS_Pic2EarthPack(LOS_CMOS_PICNUM, cmos_p2gbuf))
                {
                    //出现了错误
                    case -1:
                    LOS_CMOS_OBC2TM = 3;   //状态：传输异常（文件打开失败）
                    break;

                    //传输完了，这是最后一包了
                    case 0:
                    LOS_TMTC_PicSend(cmos_p2gbuf);
                    LOS_CMOS_PICNUM = 0XFF; //0xFF的状态，不传输任何一张照片
                    LOS_CMOS_OBC2TM = 2;    //状态：传输完成
                    LOS_TM_InvTime  = LOS_CMOS_Invbuf;  //恢复先前的遥测频率
                    break;

                    //还没传输完
                    case 1: 
                    LOS_TMTC_PicSend(cmos_p2gbuf);
                    LOS_CMOS_OBC2TM = 1;    //状态：正在传输
                    break;

                    default:
                    //不应该运行到这
                }
                taskEXIT_CRITICAL();
            }
            else
            {
                LOS_CMOS_PICNUM = 0xFF;
                //决定发哪个包
                LOS_TM_SlowTMArbitrate(0x04);
                taskENTER_CRITICAL();
                LOS_TMTC_TMPack(LOS_TM_ID[4], LOS_TM_Type[4], TM_PACK_D0);
                taskEXIT_CRITICAL();
                LOS_TMTC_TMSend(TM_PACK_D0, LOS_TMTC_GetTMPackSize(LOS_TM_ID[4], LOS_TM_Type[4]));
                if (LOS_DT_TMPERMIT == 0xAA)
                {
                    LOS_DT_TMSend(TM_PACK_D0, LOS_TMTC_GetTMPackSize(LOS_TM_ID[4], LOS_TM_Type[4]));
                }

                if (LOS_TM_PackNum[4] > 0)
                {
                    LOS_TM_PackNum[4] --;
                }
                else
                {
                    LOS_TM_ID[4] = nID_AOCS;
                    LOS_TM_Type[4] = 0;
                }
                
            }
            frecnt++;
        }
        else if (frecnt == (uint16_t)((LOS_TM_FreCtrl / 4) * 6 - 1))  //29
        {
            if (LOS_CMOS_PICNUM < 100)
            {
                taskENTER_CRITICAL();
                switch(LOS_CMOS_Pic2EarthPack(LOS_CMOS_PICNUM, cmos_p2gbuf))
                {
                    //出现了错误
                    case -1:
                    LOS_CMOS_OBC2TM = 3;   //状态：传输异常（文件打开失败）
                    break;

                    //传输完了，这是最后一包了
                    case 0:
                    LOS_TMTC_PicSend(cmos_p2gbuf);
                    LOS_CMOS_PICNUM = 0XFF; //0xFF的状态，不传输任何一张照片
                    LOS_CMOS_OBC2TM = 2;    //状态：传输完成
                    LOS_TM_InvTime  = LOS_CMOS_Invbuf;  //恢复先前的遥测频率
                    break;

                    //还没传输完
                    case 1: 
                    LOS_TMTC_PicSend(cmos_p2gbuf);
                    LOS_CMOS_OBC2TM = 1;    //状态：正在传输
                    break;

                    default:
                    //不应该运行到这
                }
                taskEXIT_CRITICAL();
            }
            else
            {
                LOS_CMOS_PICNUM = 0xFF;
                //决定发哪个包
                LOS_TM_SlowTMArbitrate(0x05);
                taskENTER_CRITICAL();
                LOS_TMTC_TMPack(LOS_TM_ID[5], LOS_TM_Type[5], TM_PACK_D0);
                taskEXIT_CRITICAL();
                LOS_TMTC_TMSend(TM_PACK_D0, LOS_TMTC_GetTMPackSize(LOS_TM_ID[5], LOS_TM_Type[5]));
                if (LOS_DT_TMPERMIT == 0xAA)
                {
                    LOS_DT_TMSend(TM_PACK_D0, LOS_TMTC_GetTMPackSize(LOS_TM_ID[5], LOS_TM_Type[5]));
                }

                if (LOS_TM_PackNum[5] > 0)
                {
                    LOS_TM_PackNum[5] --;
                }
                else
                {
                    LOS_TM_ID[5] = nID_AOCS;
                    LOS_TM_Type[5] = 1;
                }
            }

            //如果是6包模式，到这就需要清0了
            if (frecnt >= (LOS_TM_FreCtrl + (LOS_TM_InvTime * 10) - 1))
            {
                frecnt = 0;
            }
            else
            {
                frecnt++;
            }
        }
        else if (frecnt >= (LOS_TM_FreCtrl + (LOS_TM_InvTime * 10) - 1)) //如果间隔为0，就是19，其实运行不到这; 如果要传两包照片的话，间隔至少要设置成1
        {
            frecnt = 0;
        }

        //遥测间隔设置时间上限控制
        if(LOS_TM_AdjustInvDur > 0)
        {
            if (invsetcnt<9)
            {
                invsetcnt++;
            }
            else
            {
                invsetcnt = 0;
                LOS_TM_AdjustInvDur--;
            }
        }
        else
        {
            invsetcnt = 0;
            LOS_TM_InvTime = 28;
        }
        
        LOS_Task_DelayUntil(&LastWakeTime, 100);
    }
}

/** @fn Task_HighFreq_Func(void *pvParameteres)
*   @brief 低优先级高频线程
*/
void Task_HighFreq_Func(void *pvParameteres)
{
    static uint32_t bhr = 0;             //FATFS读操作需要，表示读了多少
    uint8_t FATFS_Result = 0;            //FATFS操作返回值，用于判断FATFS操作是否成功。
    static uint32_t offset = 0;          //偏移地址
    static uint8_t errcnt = 0;

    
    TickType_t LastWakeTime;
    LastWakeTime = LOS_Task_GetTick();
    while(1)
    {
        if (LOS_HFT_STA == 2) //对上注程序进行CRC32计算
        {
            if ((CRC32_SD_OFFSET < LOS_UPLOAD_FileReceived) && (LOS_UPLOAD_FileReceived > 0))
            {
                do
                {
                    FATFS_Result = f_open(&rfile_crc32, "1:upd.bin", FA_OPEN_EXISTING | FA_READ);
                    errcnt++;   
                } while ((FATFS_Result!=FR_OK) && (errcnt < 20));

                errcnt = 0;
                
                if (FATFS_Result == FR_OK)
                {
                    f_lseek(&rfile_crc32, CRC32_SD_OFFSET);
                    if ((LOS_UPLOAD_FileReceived - CRC32_SD_OFFSET) <= 1028)
                    {
                        f_read(&rfile_crc32, crcbuf, LOS_UPLOAD_FileReceived - CRC32_SD_OFFSET, &bhr);
                        //LOS_W25Q64_ReadData(ADDR_UP_PROGRAM+CRC32_SD_OFFSET, crcbuf, LOS_UPLOAD_FileReceived - CRC32_SD_OFFSET);
                        memcpy(&CRC32_SD_SAVE, &crcbuf[LOS_UPLOAD_FileReceived - CRC32_SD_OFFSET - 4], 4);
                        CRC32_SD_OBCCAL = LOS_FP_CRC32Cal(crcbuf, LOS_UPLOAD_FileReceived - CRC32_SD_OFFSET - 4, CRC32_SD_OBCCAL^0xFFFFFFFF);   //SD卡中存储的文件最后四个字节为CRC32值，所以要-4
                        CRC32_SD_OFFSET += (LOS_UPLOAD_FileReceived - CRC32_SD_OFFSET);
                    }
                    else
                    {
                        f_read(&rfile_crc32, crcbuf, 1024, &bhr);
                        //LOS_W25Q64_ReadData(ADDR_UP_PROGRAM+CRC32_SD_OFFSET, crcbuf, 1024);
                        CRC32_SD_OBCCAL = LOS_FP_CRC32Cal(crcbuf, 1024, CRC32_SD_OBCCAL^0xFFFFFFFF);
                        CRC32_SD_OFFSET += 1024;
                    }
                    f_close(&rfile_crc32);
                }
                else
                {
                    CRC32_SD_OFFSET = 0;
                    LOS_HFT_STA = 0;
                    CRC32_SD_OBCCAL = 0;
                    LOS_UPLOAD_TC2OBC = 14;  //文件系统异常
                    f_close(&rfile_crc32);
                }
            }
            else
            {
                LOS_HFT_STA = 0;
                
            }
            LOS_WDT_Feed();
        }

        LOS_Task_DelayUntil(&LastWakeTime, 50);
    }
}


/** @fn Task_UP_Func(void* pvParameteres)
*   @brief 上注转存线程
*/
void Task_UP_Func(void* pvParameteres)
{
    TickType_t LastWakeTime;
    BaseType_t err = pdFALSE;
    uint32_t offset = 0;
    uint8_t last_flag = 0; //最后一包标志，若为1，则表明这一包是最后一包
    uint8_t fs_sta = 0;
    static uint8_t offset_before = 0;
    LOS_UPLOAD_LASTPACK = 0;

    LastWakeTime = LOS_Task_GetTick();
    while(1)
    {
        if (BinSemphr_TC != NULL)
        {
            err = LOS_BinSemphr_Take(BinSemphr_UP, portMAX_DELAY);
            LOS_WDT_Feed();
            if (err == pdTRUE)
            {
                if (LOS_UPLOAD_TC2OBC == 3)  //如果是上注的程序
                {
                    memcpy(&offset, UP_BUF, 4);
                    if (offset == LOS_UPLOAD_OffSet)
                    {
                        taskENTER_CRITICAL();
                        fs_sta = LOS_FATFS_Write("1:upd.bin", &UP_BUF[4], LOS_UPLOAD_BlockSize, LOS_UP_BASEADDR+offset, &LOS_UPFILE_SIZE);
                        taskEXIT_CRITICAL();
                        if (fs_sta == 0) //sd卡写入成功
                        {
                            //计算CRC32值
                            if (last_flag == 1) //最后一包
                            {
                                memcpy(&CRC32_TC_TRAN,&UP_BUF[4 + LOS_UPLOAD_BlockSize - 4], 4); //前4个字节是偏移地址所以+4，后4个字节是传输过来的CRC值所以-4，至于为什么不直接合并，因为我乐意
                                LOS_HFT_STA = 2;
                            }
                            else
                            {
                                
                            }

                            LOS_UPLOAD_OffSet += LOS_UPLOAD_BlockSize;
                            LOS_UPLOAD_BlockCnt++;
                            LOS_UPLOAD_FileReceived += LOS_UPLOAD_BlockSize;
                            if ((LOS_UPLOAD_FileSize + LOS_UP_BASEADDR - LOS_UPLOAD_FileReceived) <= TMTC2SD_UPFSIZE) //最后一包小于等于240字节
                            {
                                LOS_UPLOAD_BlockSize = LOS_UPLOAD_FileSize + LOS_UP_BASEADDR - LOS_UPLOAD_FileReceived;
                                last_flag = 1;
                                LOS_UPLOAD_LASTPACK = 1;
                            }
                            
                            if (LOS_UPLOAD_FileSize + LOS_UP_BASEADDR == LOS_UPLOAD_FileReceived)  //传输完成
                            {
                                LOS_UPLOAD_BlockSize = TMTC2SD_UPFSIZE;
                                LOS_UPLOAD_ReadFinishTime = LOS_Time_Sec;  //记录一下传输完成时刻
                                LOS_UPLOAD_TC2OBC = 4;
                                last_flag = 0;
                                LOS_UPLOAD_LASTPACK = 0;
                            }
                        }
                        else
                        {
                            LOS_UPLOAD_TC2OBC = 14; //文件系统异常
                        }
            
                    }
                }
                else if (LOS_UPLOAD_DT2OBC == 3)
                {
                    memcpy(&offset, UP_BUF, 4);
                    if (offset == LOS_UPLOAD_OffSet)
                    {
                        taskENTER_CRITICAL();
                        fs_sta = LOS_FATFS_Write("1:upd.bin", &UP_BUF[4], LOS_UPLOAD_BlockSize, LOS_UP_BASEADDR+offset, &LOS_UPFILE_SIZE);
                        taskEXIT_CRITICAL();
                        if (fs_sta == 0) //sd卡写入成功
                        {
                            //计算CRC32值
                            if (last_flag == 1) //最后一包
                            {
                                memcpy(&CRC32_TC_TRAN,&UP_BUF[4 + LOS_UPLOAD_BlockSize - 4], 4); //前4个字节是偏移地址所以+4，后4个字节是传输过来的CRC值所以-4，至于为什么不直接合并，因为我乐意
                                LOS_HFT_STA = 2;
                            }
                            else
                            {
                                
                            }

                            LOS_UPLOAD_OffSet += LOS_UPLOAD_BlockSize;
                            LOS_UPLOAD_BlockCnt++;
                            LOS_UPLOAD_FileReceived += LOS_UPLOAD_BlockSize;
                            if ((LOS_UPLOAD_FileSize + LOS_UP_BASEADDR  - LOS_UPLOAD_FileReceived) <= TMTC2SD_UPFSIZE) //最后一包小于等于240字节
                            {
                                LOS_UPLOAD_BlockSize = LOS_UPLOAD_FileSize + LOS_UP_BASEADDR  - LOS_UPLOAD_FileReceived;
                                last_flag = 1;
                                LOS_UPLOAD_LASTPACK = 1;
                            }
                            
                            if (LOS_UPLOAD_FileSize + LOS_UP_BASEADDR  == LOS_UPLOAD_FileReceived)  //传输完成
                            {
                                LOS_UPLOAD_BlockSize = TMTC2SD_UPFSIZE;
                                LOS_UPLOAD_ReadFinishTime = LOS_Time_Sec;  //记录一下传输完成时刻
                                LOS_UPLOAD_DT2OBC = 4;
                                last_flag = 0;
                                LOS_UPLOAD_LASTPACK = 0;
                            }
                        }
                        else
                        {
                            LOS_UPLOAD_DT2OBC = 14; //文件系统异常
                        }
            
                    }
                }

                if (STA_CMOS.readsta == 2)  //如果是小相机的照片
                {
                    STA_CMOS.recnt = 0;
                    if (STA_CMOS.offset == STA_CMOS.readoffset)
                    {
                        taskENTER_CRITICAL();
                        fs_sta = LOS_FATFS_Write("1:cms.bin", STA_CMOS.picbuf, 256, 2048 + STA_CMOS.pictotalsize + STA_CMOS.readoffset, &STA_CMOS.filesize);
                        taskEXIT_CRITICAL();
                        if (fs_sta == 0)
                        {
                            STA_CMOS.readoffset += 256;
                        }
                        else
                        {
                            STA_CMOS.readsta = 3; //文件系统错误
                        }
                    }

                    if (STA_CMOS.readoffset >= STA_CMOS.lastpiclen - 1) //存完了
                    {
                        LOS_CMOS_UpdateSDMSG(STA_CMOS.piccnt, STA_CMOS.lastpiclen);
                        STA_CMOS.readsta = 5;
                    }
                }

                
            }
        }
        LOS_Task_DelayUntil(&LastWakeTime, 1);
    }
}


/** @fn void Task_Update_Func(void *pvParameteres)
*   @brief 在轨上注软件更新线程
*   @note 该线程默认挂起，当PERMIT_UPLOAD_SD2FLASH == 1时恢复，开始运行。若PERMIT_UPLOAD_SD2FLASH不为1，会被自动挂起。
*/
#ifdef NOW_FLASH0
void Task_Update_Func(void *pvParameteres)
{
    static uint32_t EnterCnt = 0;        //循环执行的次数
    static uint8_t CodeBuf[1024];        //代码buffer
    static uint8_t FLAG_Finish = 0;
    static Fapi_FlashBankType Fapi_FlashBank = Fapi_FlashBank1;

    static uint32_t bhr = 0;             //FATFS读操作需要，表示读了多少
    uint8_t FATFS_Result = 0;            //FATFS操作返回值，用于判断FATFS操作是否成功。
    static uint32_t sector_now = 0;      //FLASH当前操作的sector
    static uint32_t sector_size = 0;     //当前sector的大小
    static uint32_t sector_upcnt = 0x00;    //sector向上计数指针，作为写入偏移量使用，初始化值为烧写起点偏移地址
    uint32_t fcnt = 0;                    //FATFS操作计数器
    if(LOS_FLASH_ID == Fapi_FlashBank0)  
    {
        Fapi_FlashBank = Fapi_FlashBank1;
    }
    else  //禁止FLASH1程序乱写
    {
        PERMIT_UPLOAD_SD2FLASH = 0;
    }

    if (PERMIT_UPLOAD_SD2FLASH == 1)
    {
        while(1)
        {
            LOS_WDT_Feed();
            STATE_UPLOAD_SD2FLASHDONE = 0;   //SD卡至FLASH完成标志位：未完成
            if (sector_size == 0)   //如果sector_size为0，要么是刚开始，要么是上一个sector用完了，此时再获取sector大小信息
            {
                sector_size = gSector_List[find_sector(Fapi_FlashBank, sector_now)].size - sector_upcnt;    //这样就可以任意设置烧写起点
            }

            if (EnterCnt==0)
            {
                do
                {
                    FATFS_Result = f_open(&rfile, "1:upd.bin", FA_OPEN_EXISTING | FA_READ);    //若是第一次进入该线程，应先打开文件
                    fcnt++;
                } while ((FATFS_Result != FR_OK) && (fcnt < 20));
                fcnt = 0;
                
                if (FATFS_Result == FR_OK)
                {
                    LOS_SD2FLASH_SIZE = f_size(&rfile);    //获取.bin文件大小
                    STATE_UPLOAD_OPENFILE = 0;

                    f_read(&rfile, CodeBuf, 1024, &bhr);
                    LOS_EnterAdminMode();
                    LOS_Flash_EraseSector(Fapi_FlashBank7,1);
                    LOS_Flash_EraseSector(Fapi_FlashBank7,3);
                    LOS_Flash_EraseBanks(Fapi_FlashBank);   //第一次写，先擦除再写
                    LOS_Flash_WriteData(Fapi_FlashBank, sector_now, sector_upcnt, CodeBuf, 1024);
                    LOS_ExitAdminMode();
                    LOS_WDT_Feed();
                    sector_size -= 1024;
                    LOS_SD2FLASH_SIZE -= 1024;
                    sector_upcnt += 1024;
                    EnterCnt++;
                }
                else
                {
                    f_close(&rfile);
                    STATE_UPLOAD_OPENFILE = 1;
                    EnterCnt = 0; //计数器counter thread 
                }  
            }
            else
            {
                if (LOS_SD2FLASH_SIZE<1024) //如果是最后一包数据，则不能按照1024大小读取`
                {
                    f_read(&rfile, CodeBuf, LOS_SD2FLASH_SIZE, &bhr);
                    LOS_EnterAdminMode();
                    LOS_Flash_WriteData(Fapi_FlashBank, sector_now, sector_upcnt, CodeBuf, LOS_SD2FLASH_SIZE);
                    LOS_ExitAdminMode();
                    LOS_WDT_Feed();
                    f_close(&rfile);
                    STATE_UPLOAD_SD2FLASHDONE = 1;   //SD卡至FLASH完成标志位：已完成
                    EnterCnt = 0;                    //以下是各种计数器清零，为下一次烧写做准备
                    PERMIT_UPLOAD_SD2FLASH = 0;
                    sector_size = 0;
                    sector_now = 0;
                    LOS_SD2FLASH_SIZE = 0;
                    sector_upcnt = 0x00;
                    FLAG_Finish = 1;

                }
                else
                {
                    f_read(&rfile, CodeBuf, 1024, &bhr);
                    LOS_EnterAdminMode();
                    LOS_Flash_WriteData(Fapi_FlashBank, sector_now, sector_upcnt, CodeBuf, 1024);
                    LOS_ExitAdminMode();
                    LOS_WDT_Feed();
                    sector_size -= 1024;
                    LOS_SD2FLASH_SIZE -= 1024;
                    sector_upcnt += 1024;
                    EnterCnt++;
                }
            }

            if (sector_size == 0)   //当前sector被写满了，则到下一个sector；最后一次写完程序时，由于sector_size被清0，也会进入这个情况，所以在下一个if里还要再清零一次
            {
                sector_now++;
                sector_upcnt = 0;
            }

            if (FLAG_Finish == 1)
            {
                FLAG_Finish = 0;
                sector_now = 0;
                sector_upcnt = 0x00;
                LOS_UPLOAD_DownFinishTime = LOS_Time_Sec;  //记录烧写结束时刻
                LOS_Task_Suspend(Task_Update_Handle);  //挂起任务
            }
            LOS_Task_Delay(5);
        }
    }
}
#endif

/** @fn Task_TC_Func(void* pvParameteres)
*   @brief 遥控线程
*/
void Task_TC_Func(void* pvParameteres)
{
    TickType_t LastWakeTime;
    BaseType_t err = pdFALSE;

    LastWakeTime = LOS_Task_GetTick();
    while(1)
    {
        if (BinSemphr_TC != NULL)
        {
            err = LOS_BinSemphr_Take(BinSemphr_TC, portMAX_DELAY);
            if (err == pdTRUE)
            {
                LOS_TMTC_TCUnpack(TC_CMD_BUF,8*TC_FCNT);
            }
        }
        LOS_Task_DelayUntil(&LastWakeTime, 1);
    }
}


/** @fn Task_UARTRcv_Func(void* pvParameteres)
*   @brief 串口接收线程
*/
void Task_UARTRcv_Func(void* pvParameteres)
{
    TickType_t LastWakeTime;
    LastWakeTime = LOS_Task_GetTick();

    while(1)
    {
        taskENTER_CRITICAL();
        LOS_MAX14830_MsgHandle();
        taskEXIT_CRITICAL();
        LOS_Task_DelayUntil(&LastWakeTime, 50);
    }
}

/** @fn Task_AOCS_Func(void* pvParameteres)
*   @brief 姿控线程
*/
void Task_AOCS_Func(void* pvParameteres)
{
    LOS_Tick_t LastWakeTime;
    LastWakeTime = LOS_Task_GetTick();
    uint8_t enter_flag = 0;
    uint8_t EnterAocsFlag = 0;//用来标识是否可以进入姿控模式
    uint8_t bufff = 0;
    static uint8_t cmossendcnt = 0;  //OBC通过串口发送cmos数据包计数
    static uint32_t thread_delaytime = 250;
    static uint8_t dtautocnt = 0;  //自动开数传控制量 

    while(1)
    {
        if (enter_flag == 0)  //如果是第一次进入该线程
        {
            LOS_CAN_Radio();  //发个CAN广播帧（方便动力学测试用）
            //小相机照片文件初始化
            LOS_CMOS_FileInit();
            enter_flag++;
        }

        if (FR_DELAYEN == 0XABED5CFA) //会延时
        {
            if (LOS_Time_SecFromBoot >= FR_DELAYDUR) //过了延时时间再进飞行程序
            {
                if (EnterAocsFlag == 0)
                {
                    EnterAocsFlag = LOS_FP_Procedure(LOS_Time_SecFromBoot-FR_DELAYDUR);
                }
            }
        }
        else
        {
            if (EnterAocsFlag == 0)
            {
                EnterAocsFlag = LOS_FP_Procedure(LOS_Time_SecFromBoot + 80);
            }
        }

        //2700s后再烧绳
        if ((LOS_Time_SecFromBoot >= FR_DELAYDUR + 100 + 2700) && (LOS_Time_SecFromBoot < FR_DELAYDUR + 100 + 2700 + 100))
        {
            LOS_FP_ExtraTK(LOS_Time_SecFromBoot - FR_DELAYDUR - 100 -2700);
        }

        
        //展帆和开星敏
//        if (aocs_g_output_struct.Sun_Flag == 0xAA)
//        {
//            if (LOS_TK_SEL[TKSAX1_CODE] != 0X55) //0X55说明已经走完流程了，没走的时候是0
//            {
//                if (FR_TKSAEN == 0XABED5CFA) //允许展帆版
//                {
//                    LOS_TK_SEL[TKSAX1_CODE] = 0xAA;
//                    LOS_TK_SEL[TKSAX2_CODE] = 0xAA;
//                }
//            }
//
//            LOS_SSY_PWROn();
//            LOS_SSZ_PWROn();
//        }
        
       
        /* 测试模式维护 */
        if (LOS_TESTM_FLAG == 1)
        {
            LOS_TESTM_LEFT = LOS_TESTM_DUR + LOS_TESTM_ENT - LOS_Time_SecFromBoot; //计算测试模式剩余时长
            if ((LOS_TESTM_DUR + LOS_TESTM_ENT) <= LOS_Time_SecFromBoot) //测试模式到时，退出测试模式
            {
                LOS_TESTM_FLAG = 0;
                LOS_TESTM_LEFT = 0;
                LOS_TESTM_DUR = 0;
                LOS_TESTM_ENT = 0;
            }
        }

        /* 更新FRAM中的时间，两小时更新一次 */
        if ((LOS_Time_SecFromBoot % 7200) == 0 && (LOS_Time_SecFromBoot != 0))
        {
            LOS_FVAR_ModifyFRUTC(LOS_Time_Sec);
        }

        /* 12h(由FR_DTAUTO[0]定义)未收到指令自动开数传 */
        if (LOS_Time_SecFromBoot - LOS_TC_LASTCMDTIME >= FR_DTAUTO[0])
        {
            if (STA_EPS.Mother_Vol > FR_DTAUTO[1])
            {
                if (dtautocnt < 10)  //连续10次母线电压都大于阈值
                {
                    dtautocnt++;
                }
                else if (dtautocnt == 10)
                {
                    LOS_DTBB_PWROn();
                    LOS_DTCH_PWROn();
                    LOS_TC_LASTCMDTIME = LOS_Time_SecFromBoot;
                    dtautocnt++;
                }
            }
            else
            {
                dtautocnt = 0;
            }
        }

        /* 数传看门狗 */
        if ((STA_DT.ENWDT == 0XAA) && (STA_EPS.SWITCH_PD[SWITCH_DTBB_PD - 1] == 0XAA))
        {
            if (LOS_Time_SecFromBoot - STA_DT.boottime >= 120)  //启动120s后开始判
            {
                if (LOS_Time_SecFromBoot - STA_DT.boottime == 120)
                {
                    STA_DT.askcnt = 0;
                }

                if (STA_DT.REC != 1)  //未识别
                {
                    LOS_DTBB_PWROff();
                    LOS_DTCH_PWROff();
                }
                else
                {
                    if (STA_DT.askcnt > 50) //50次请求都没有响应
                    {
                        LOS_DTBB_PWROff();
                        LOS_DTCH_PWROff();
                    }
                }
            }
        }

        /* 电源板自动维护 */
        //40S未收到PCDU遥测复位PCDU
        if (LOS_Time_SecFromBoot - STA_EPS.PD_LastTime > 40)
        {
            LOS_EPS_ResetPDH();
            STA_EPS.PD_LastTime = LOS_Time_SecFromBoot;
        }

        if (LOS_Time_SecFromBoot - STA_EPS.TC_LastTime > 40)
        {
            LOS_EPS_ResetTCH();
            STA_EPS.TC_LastTime = LOS_Time_SecFromBoot;
        }

        /* 姿控程序 */
        if (EnterAocsFlag == 1 && LOS_TESTM_FLAG == 0)//
        {
            if (AOCS_Enter_Times == 0)
            {
                LOS_FVAR_ModifyDELAYEN(0XABED5CFA);
            }

//            if (MODE_AOCS.mode != Safe) //安全模式下姿控程序不运行
//            {
//                AttMainFun(MODE_AOCS.mode);
//                /* 健康管理：姿控程序判断单机故障，星务进行处理 */
//            }
            /* 工作模式切换 */
            LOS_AOCS_ChangeMode(MODE_AOCS.AM_TCFLAG);
            /* 模式切换操作 */
        }
        else
        {
            
        }

        if (LOS_TESTM_FLAG == 1)
        {
            //LOS_BinSemphr_Give(BinSemphr_MG);
            LOS_MagTrqPermit = 1;
        }

        //检查并执行遥控队列
        LOS_FP_CheckTable(LOS_Time_Sec);
        //查找最近的一条延时遥控指令
        LOS_FP_FindFirstDelayCMD();
        //获取列表中的待执行任务数量
        LOS_TC_TaskNum = LOS_FP_GetTableSize();

        thread_delaytime = 250;
        //如果不在测试模式
        if (LOS_TESTM_FLAG == 0)
        {
            if (LOS_MagTrqPermit == 1)  //要采集了
            {
                LOS_MagTrq_TC(nID_MAGTRQX1, 0);
                LOS_MagTrq_TC(nID_MAGTRQY1, 0);
                LOS_MagTrq_TC(nID_MAGTRQX2, 0); 
                LOS_MagTrq_TC(nID_MAGTRQY2, 0);
                LOS_MagTrq_TC(nID_MAGTRQZ2, 0);
                LOS_MagTrq_TC(nID_MAGTRQZ1, 0);
                LOS_Task_DelayUntil(&LastWakeTime, 50);
                LOS_MagTrqPermit = 0;
                thread_delaytime = 250 - 50;
                LOS_MagMe_GetField();
                LOS_MagMe_GetField_Dyn();
            }
        }
        else
        {
            taskENTER_CRITICAL();
            LOS_MagMe_GetField();
            taskEXIT_CRITICAL();
            LOS_MagMe_GetField_Dyn();
        }

        LOS_Task_DelayUntil(&LastWakeTime, thread_delaytime);
    }
}


/** @fn Task_Attitude_Func(void* pvParameteres)
*   @brief 卫星状态采集线程
*/
void Task_Attitude_Func(void* pvParameteres)
{
    uint8_t jmpflash1=0xAA;
    uint8_t eps_cnt = 0;
    uint8_t navicnt = 0;
    TickType_t LastWakeTime;
    static uint8_t navientflg = 0;
    static uint16_t MAXLast_CNT = 0;
    static uint8_t MAXErr_CNT = 0;
    uint8_t getfsizecnt = 0;
    uint8_t FATFS_Result = 0;            //FATFS操作返回值，用于判断FATFS操作是否成功。
    uint8_t printnum[4];
    uint8_t ST_CNT = 0;
    static uint8_t magmecnt = 0;
    static uint8_t RSTCNT = 0;
    static uint8_t satacnt = 0;   //存储板遥测请求计数器
    static uint8_t camcnt = 0;    //高分相机遥测请求计数器
    uint8_t testbytes[8] = {0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55};
    static uint8_t FotonAmur_cnt = 0;
    uint8_t W25Q64_JID[3];
    uint8_t W25Q64_TESTCNT = 0;
    uint8_t W25Q64_TBUF[16];
    uint8_t W25Q64_RBUF[16];
    static uint8_t TMArgCnt = 0; //测控请求工参节拍控制
    static uint8_t DTArgCnt = 0; //数传请求工参节拍控制
    static uint8_t GNSSArgCnt = 0; //GNSS请求工参节拍控制
    uint8_t errcnt = 0;

    LastWakeTime = LOS_Task_GetTick();

    while(1)
    {
    //时空表状态轮询
    if (ST_PollFlag == 1)
    {
        if (ST_CNT >= 4)
        {
            LOS_SpaceTime_GetSta();
            ST_CNT = 0;

        }
        else
        {
            ST_CNT++;
        }
    }



    //上注跳转指令处理
       if (PERMIT_UPLOAD_SD2FLASH == 1)
       {
            #ifdef NOW_FLASH0
            LOS_Task_Resume(Task_Update_Handle);
            #endif
       }
       else if (PERMIT_UPLOAD_SD2FLASH == 2)    //如果是第一次
       {
            #ifdef NOW_FLASH0
            LOS_Task_Suspend(Task_Update_Handle);
            #endif
            PERMIT_UPLOAD_SD2FLASH = 0;
       }

        if (PERMIT_UPLOAD_JUMP == 10) //复位后从FLASH0运行
        {
            LOS_EnterAdminMode();
            jmpflash1=0xAA;
            LOS_Flash_EraseSector(Fapi_FlashBank7,16);
            LOS_Flash_WriteData(Fapi_FlashBank7, 16, 0, &jmpflash1, 1);
            LOS_ExitAdminMode();
            PERMIT_UPLOAD_JUMP = 0;
            memcpy(&FLASH_WHERE,0xF0210000,1);
        }else if (PERMIT_UPLOAD_JUMP == 20) //复位后从FLASH1运行
        {
            LOS_EnterAdminMode();
            jmpflash1=0x55;
            LOS_Flash_EraseSector(Fapi_FlashBank7,16);
            LOS_Flash_WriteData(Fapi_FlashBank7, 16, 0, &jmpflash1, 1);
            LOS_ExitAdminMode();
            PERMIT_UPLOAD_JUMP = 0;
            memcpy(&FLASH_WHERE,0xF0210000,1);
        }

        //从测控读取上注程序
        if (LOS_UPLOAD_TC2OBC == 1)  //初始化，核对上注文件信息
        {
            if (LOS_UPLOAD_CNT == 0)
            {
                //LOS_TMTC_SetFile(LOS_UPLOAD_FileNum);  //设置待操作文件
                LOS_UPLOAD_FileReceived = 0;
                CRC32_TC_TRAN = 0;
                CRC32_SD_OBCCAL = 0;
                CRC32_SD_SAVE = 0;
                LOS_UPLOAD_CNT++;
            }
            else if (LOS_UPLOAD_CNT < 14 && LOS_UPLOAD_CNT > 0)
            {
                LOS_UPLOAD_CNT++;       
            }
            else if (LOS_UPLOAD_CNT == 14)
            {
                LOS_UPLOAD_TC2OBC = 2;
                LOS_UPLOAD_CNT = 0;
            }
        }
        else if (LOS_UPLOAD_TC2OBC == 2)
        {
            if (LOS_UPLOAD_CNT == 0)
            {
                LOS_TMTC_SetTargetnID(nID_OBC);  //设置目标nID
                LOS_UPLOAD_CNT++;
            }
            else if (LOS_UPLOAD_CNT < 14 && LOS_UPLOAD_CNT > 0)
            {
                LOS_UPLOAD_CNT++;       
            }
            else if (LOS_UPLOAD_CNT == 14)
            {
                LOS_UPLOAD_TC2OBC = 3;
                LOS_UPLOAD_CNT = 0;
            }
        }
        else if (LOS_UPLOAD_TC2OBC == 3)
        {
            if (LOS_UPLOAD_CNT == 0)
            {
                //与测控中的文件号不一致，则不执行
                if (LOS_UPLOAD_FileNum != STA_TMTC.FTP_FileNum)
                {
                    LOS_UPLOAD_TC2OBC = 12;  //异常情况：待操作文件号不一致
                }
                //与测控中的文件大小不一致，则不执行
                if (LOS_UPLOAD_FileSize != STA_TMTC.FTP_FileSize)
                {
                    LOS_UPLOAD_TC2OBC = 13;  //异常情况：文件大小不一致
                }

                LOS_UPLOAD_CNT++;
                LOS_UPLOAD_OffSet = 0;
            }
            else
            {
                LOS_TMTC_ReadBlock(LOS_UPLOAD_OffSet, LOS_UPLOAD_BlockSize);
            }

        }
        else if (LOS_UPLOAD_TC2OBC == 5) //地面中止
        {
            LOS_UPLOAD_CNT = 0;
        }


        //从数传读取上注程序
        if (LOS_UPLOAD_DT2OBC == 1)  //初始化，核对上注文件信息
        {
            if (LOS_UPLOAD_CNT == 0)
            {
                LOS_DT_SetFile(LOS_UPLOAD_FileNum); //设置待操作文件
                LOS_UPLOAD_FileReceived = 0;
                CRC32_TC_TRAN = 0;
                CRC32_SD_OBCCAL = 0;
                CRC32_SD_SAVE = 0;
                LOS_UPLOAD_CNT++;
            }
            else if (LOS_UPLOAD_CNT < 14 && LOS_UPLOAD_CNT > 0)
            {
                LOS_UPLOAD_CNT++;       
            }
            else if (LOS_UPLOAD_CNT == 14)
            {
                LOS_UPLOAD_DT2OBC = 2;
                LOS_UPLOAD_CNT = 0;
            }
        }
        else if (LOS_UPLOAD_DT2OBC == 2)
        {
            if (LOS_UPLOAD_CNT == 0)
            {
                LOS_UPLOAD_CNT++;
            }
            else if (LOS_UPLOAD_CNT < 14 && LOS_UPLOAD_CNT > 0)
            {
                LOS_UPLOAD_CNT++;       
            }
            else if (LOS_UPLOAD_CNT == 14)
            {
                LOS_UPLOAD_DT2OBC = 3;
                LOS_UPLOAD_CNT = 0;
            }
        }
        else if (LOS_UPLOAD_DT2OBC == 3)
        {
            if (LOS_UPLOAD_CNT == 0)
            {
                //先保护，如果没有设置相关参数，则不执行
                //与数传中的文件号不一致，则不执行
                if (LOS_UPLOAD_FileNum != STA_DT.FTP_FileNum)
                {
                    LOS_UPLOAD_DT2OBC = 12;  //异常情况：待操作文件号不一致
                }
                //与数传中的文件大小不一致，则不执行
                if (LOS_UPLOAD_FileSize != STA_DT.FTP_FileSize)
                {
                    LOS_UPLOAD_DT2OBC = 13;  //异常情况：文件大小不一致
                }
                LOS_UPLOAD_CNT++;
                LOS_UPLOAD_OffSet = 0;
            }
            else
            {
                LOS_DT_ReadBlock(LOS_UPLOAD_OffSet, LOS_UPLOAD_BlockSize);
            }
        }
        else if (LOS_UPLOAD_DT2OBC == 5) //地面中止
        {
            LOS_UPLOAD_CNT = 0;
        }

        /* 从小相机读取指定照片 */
        {
            if (STA_CMOS.readsta == 1) 
            {
                LOS_CMOS_PhotoLength(STA_CMOS.picid_TC);                        //需要先获取一下将读取的照片长度
                STA_CMOS.piccnt = LOS_CMOS_GetSDPicNum(&STA_CMOS.pictotalsize); //获取一下SD卡的照片存储情况
                STA_CMOS.readoffset = 0;
                STA_CMOS.recnt = 0;
            }
            else if (STA_CMOS.readsta == 2)
            {
                LOS_CMOS_ReadPhoto((uint32_t)STA_CMOS.picid_TC, STA_CMOS.readoffset, 256);
                STA_CMOS.recnt++;
                if (STA_CMOS.recnt > 40)
                {
                    STA_CMOS.readsta = 4; //相机无响应超时，退出读取
                }
            }
        }

        LOS_Task_DelayUntil(&LastWakeTime, 15);

        LOS_FW_GetState(FW_X);

        LOS_Task_DelayUntil(&LastWakeTime, 20);

        {/*太敏遥测*/
            /*** 太敏遥测请求 ***/
            LOS_SunSensor_GetSta();
        }

        LOS_Task_DelayUntil(&LastWakeTime, 20);

        LOS_FW_GetState(FW_Y);

        {/*光纤陀螺健康管理*/
            /*** 光纤陀螺遥测请求 ***/
            taskENTER_CRITICAL();
            LOS_YH50_SendCMD(0X0000);
            taskEXIT_CRITICAL();
        }

        LOS_Task_DelayUntil(&LastWakeTime, 20);

        {/*星敏遥测*/
            if (STA_SSY.REC == 1)
            {
                /*** 星敏Y遥测请求 ***/
                if (STA_SSY.FSM == 0)
                {
                    //LOS_StarSensor_CMD(nID_StarSensorY,StarCMD_Correct);
                    STA_SSY.FSM++;
                }
                else if (STA_SSY.FSM > 0 && STA_SSY.FSM < 4)
                {
                    STA_SSY.FSM++;
                }
                else if (STA_SSY.FSM == 4)
                {
                    LOS_StarSensor_CMD(nID_StarSensorY,StarCMD_Attitude);
                    STA_SSY.FSM++; 
                }
                else if (STA_SSY.FSM > 4 && STA_SSY.FSM < 8)
                {
                    //等待星敏进入姿态测量模式
                    STA_SSY.FSM++;
                }
                else
                {
                    LOS_StarSensor_CMD(nID_StarSensorY,StarCMD_Short);
                    STA_SSY.HL_TXF = 1;
                }
            }
        }

        LOS_Task_DelayUntil(&LastWakeTime, 15);
        
        LOS_FW_GetState(FW_S);

        LOS_Task_DelayUntil(&LastWakeTime, 15);
        
        //PCDU遥测请求
        if(LOS_Time_SecFromBoot > 1)
        {
            LOS_EPS_GetSTA();
        }
        
        LOS_Task_DelayUntil(&LastWakeTime, 15);
            
        //存储板遥测请求
        if(STA_SATA.REC == 1)
        {
            if (satacnt < 7)
            {
                satacnt++;
            }
            else
            {
                LOS_SATA_GetState();
                satacnt = 0;
            }
        }

        //高分相机
        if (STA_CIOMPCam.CMD == 1)
        {
            if (camcnt < 7)
            {
                camcnt++;
            }
            else
            {
                LOS_CIOMPCam_GetState();
                camcnt = 0;
            }
        }

        LOS_Task_DelayUntil(&LastWakeTime, 20);
        
        {   //星敏Z
            /*** 星敏Z遥测请求 ***/
            if (STA_SSZ.REC == 1)
            {
                if (STA_SSZ.FSM == 0)
                {
                    //LOS_StarSensor_CMD(nID_StarSensorZ,StarCMD_Correct);
                    STA_SSZ.FSM++;
                }
                else if (STA_SSZ.FSM > 0 && STA_SSZ.FSM < 4)
                {
                    STA_SSZ.FSM++;
                }
                else if (STA_SSZ.FSM == 4)
                {
                    LOS_StarSensor_CMD(nID_StarSensorZ,StarCMD_Attitude);
                    STA_SSZ.FSM++; 
                }
                else if (STA_SSZ.FSM > 4 && STA_SSZ.FSM < 8)
                {
                    //等待星敏进入姿态测量模式
                    STA_SSZ.FSM++;
                }
                else
                {
                    LOS_StarSensor_CMD(nID_StarSensorZ,StarCMD_Short);
                    STA_SSZ.HL_TXF = 1;
                }
            }
        }

        LOS_Task_DelayUntil(&LastWakeTime, 20);

        if (LOS_UPLOAD_TC2OBC != 3 && TMTC_PERMITARG != 0X55) //读取上注文件的时候不要单机遥测
        {/* 测控 */
            //测控板遥测请求，2s一次
            if (TMArgCnt < 4)
            {
                TMArgCnt++;
            }
            else if (TMArgCnt == 4)
            {
                LOS_TMTC_GetStatus();
                TMArgCnt++;
            }
            else if (TMArgCnt >= 8)
            {
                TMArgCnt = 0;
            }
            else
            {
                TMArgCnt++;
            }
        }

        LOS_Task_DelayUntil(&LastWakeTime, 20);

        if (LOS_UPLOAD_TC2OBC != 3)
        {
            if (STA_DT.REC == 1)
            {/* 数传 */
                //数传遥测请求，2s一次
                if (DTArgCnt < 4)
                {
                    DTArgCnt++;
                }
                else if (DTArgCnt == 4)
                {
                    LOS_DT_CMD0BYTE(0X81);
                    STA_DT.askcnt++;
                    DTArgCnt++;
                }
                else if (DTArgCnt >= 8)
                {
                    DTArgCnt = 0;
                }
                else if (DTArgCnt < 8)
                {
                    DTArgCnt++;
                }
            }
        }
        LOS_Task_DelayUntil(&LastWakeTime, 20);

        {/* GNSS */
            if (GNSSArgCnt ==0)
            {
                GNSSArgCnt++;
            }
            else if (GNSSArgCnt == 1)
            {
                LOS_GNSS_CMD(GNSS_CMD_StatusPolling);
                GNSSArgCnt++;
            }
            else if (GNSSArgCnt == 2)
            {
                GNSSArgCnt++;
            }
            else if (GNSSArgCnt > 2)
            {
                GNSSArgCnt = 0;
            }
        }

        LOS_Task_DelayUntil(&LastWakeTime, 20);

        LOS_FW_GetState(FW_Z);
        
        if (STA_NaviEnhance.CMD == 1)
        {/* 导航增强 */
            if (navientflg == 0)
            {
                LOS_NaviEnhance_UP();
                navientflg++;
            }

            if(navicnt < 20)
            {
                navicnt++;
            }

            if (navicnt == 10)
            {
                LOS_GNSS_CMD(GNSS_CMD_OriginPolling);                
            }

            if (navicnt == 20)
            {
                navicnt = 0;
                if (STA_NaviEnhance.TM_Type == 0)
                {
                    LOS_NaviEnhance_CMD(NaviEnhance_CMD_Status);
                }
                else if (STA_NaviEnhance.TM_Type == 1)
                {
                    LOS_NaviEnhance_CMD(NaviEnhance_CMD_Result);
                }
            }

            if (FLAG_GNSS_OriginData == 1)  //接收到原始观测量
            {
                LOS_NaviEnhance_OriginData(&BUF_GNSS_OriginData[10]);
                FLAG_GNSS_OriginData = 0;
            }
            if (navicnt < 3)
            {
                navicnt++;
            }
            else
            {
                //LOS_NaviEnhance_CMD(NaviEnhance_CMD_Status);
                navicnt = 0;
            }
        }

        //MAX14830自检
        taskENTER_CRITICAL();
        LOS_MAX14830_Check(CS_MAX1);
        LOS_MAX14830_Check(CS_MAX2);
        taskEXIT_CRITICAL();

        //MAX14830恢复
        if (MAX_RESET_FLAG == 1)
        {
            if (RSTCNT < 8)
            {
                RSTCNT++;
            }
            else
            {
                LOS_MAX14830_PowerOn();
                RSTCNT = 0;
            }
        }

        //配电扩展板恢复
        if(STA_EPS.PD_RSTFLAG)
        {
            if (STA_EPS.PD_RSTFLAG < 8)
            {
                STA_EPS.PD_RSTFLAG++;
            }
            else
            {
                STA_EPS.PD_RSTFLAG = 0;
                LOS_EPS_RecoverPDH();
            }
        }

        //热控扩展板恢复
        if(STA_EPS.TC_RSTFLAG)
        {
            if (STA_EPS.TC_RSTFLAG < 8)
            {
                STA_EPS.TC_RSTFLAG++;
            }
            else
            {
                STA_EPS.TC_RSTFLAG = 0;
                LOS_EPS_RecoverTCH();
            }
        }

        LOS_Task_DelayUntil(&LastWakeTime, 20);

        //光电传感器
        if (STA_FotonAmur.CMD == 1)
        {

            if (LOS_Time_SecFromBoot - STA_FotonAmur.PWRON_Time == 5)
            {
                //第一步：发0x00清载荷缓冲区
                if (STA_FotonAmur.flag1 == 0)
                {
                    STA_FotonAmur.flag1 = 1;
                }
            }
            else if (LOS_Time_SecFromBoot - STA_FotonAmur.PWRON_Time == 6) 
            {
                //第二步：设置时间
                STA_FotonAmur.flag1 = 0;
                if (STA_FotonAmur.flag2 == 0)
                {
                    STA_FotonAmur.flag2 = 1;
                }
            }
            else if (LOS_Time_SecFromBoot - STA_FotonAmur.PWRON_Time == 7)
            {
                //第三步：设置温度和四元数
                STA_FotonAmur.flag2 = 0;
                if (STA_FotonAmur.flag1 == 0)
                {
                    LOS_FotonAmur_NewPack();
                    STA_FotonAmur.flag1 = 1;
                }
            }
            else if (((LOS_Time_SecFromBoot - STA_FotonAmur.PWRON_Time - 7) % STA_FotonAmur.argprd) == 0)
            {
                if (FotonAmur_cnt == 2)
                {
                    LOS_FotonAmur_NewPack();
                    FotonAmur_cnt++;
                }
                else if (FotonAmur_cnt == 3)
                {
                    FotonAmur_cnt = 0;
                }
                else
                {
                    FotonAmur_cnt++;
                }
            }
        }
        else if (STA_FotonAmur.CMD == 2) //下电序列
        {
            if (LOS_Time_SecFromBoot - STA_FotonAmur.PWRDOWN_Time == 1)
            {
                if (FotonAmur_cnt == 2)
                {
                    LOS_FotonAmur_ClearBuf();
                    FotonAmur_cnt++;
                }
                else if (FotonAmur_cnt == 3)
                {
                    FotonAmur_cnt = 0;
                }
                else
                {
                    FotonAmur_cnt++;
                }
            }
            else if (LOS_Time_SecFromBoot - STA_FotonAmur.PWRDOWN_Time == 2)
            {
                if (FotonAmur_cnt == 2)
                {
                    LOS_FotonAmur_Shutdown();
                    FotonAmur_cnt++;
                }
                else if (FotonAmur_cnt == 3)
                {
                    FotonAmur_cnt = 0;
                }
                else
                {
                    FotonAmur_cnt++;
                }
            }
            else if (LOS_Time_SecFromBoot - STA_FotonAmur.PWRDOWN_Time == 6)
            {
                LOS_FotonAmur_PWROff();
            }
        }

        LOS_Task_DelayUntil(&LastWakeTime, 10);
    }
}



